package com.umeox.quranplayer.repository

import android.media.MediaMetadataRetriever
import android.os.Environment
import android.text.TextUtils
import com.umeox.moto.common.log.Logger
import com.umeox.quranplayer.db.AppDatabase
import com.umeox.quranplayer.db.model.QuranAudio
import com.umeox.quranplayer.repository.model.QuranAudioBean
import com.umeox.quranplayer.repository.model.QuranFileInfo
import com.yc.music.config.MusicConstant
import com.yc.music.utils.MusicSpUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File


/**
 * 早晨祈祷的音频文件名称
 */
const val MORNING_QURAN_FILE_NAME = "morning_remembrance"


/**
 * 晚上祈祷的音频文件名称
 */
const val NIGHT_QURAN_FILE_NAME = "evening_remembrance"

/**
 * 默认选中的音频文件名称
 */
const val DEFAULT_QURAN_TITLE = "001"

/**
 * 古兰经音频文件目标目录 /media/audio/ringtones/
 */
const val QURAN_DIR_NAME = "/extra/"



/**
 * 上次播放的音频文件名称
 */
const val SP_KEY_MUSIC_NAME = "musicName"

/**
 * 收藏列表SP key
 */
const val SP_KEY_FAVORITE_MUSIC = "musicFavorite"

/**
 * 列表请求码
 */
const val QURAN_LIST_REQUEST_CODE = 1000

/**
 * 音频列表选中回调的Intent Key
 * 列表类型
 * 用于歌曲循环时 采用哪个列表循环
 */
const val INTENT_KEY_LIST_TYPE = "musicListType"

/**
 * 音频列表选中回调的Intent Key
 * 音频名称
 * 用于定位选中的是哪首歌曲
 */
const val INTENT_KEY_AUDIO_NAME = "playName"

/**
 * 古兰经列表
 */
const val LIST_TYPE_QURAN = 1000

/**
 * 收藏列表
 */
const val LIST_TYPE_FAVORITE = 2000

/**
 * 早晨祈祷列表
 */
const val LIST_TYPE_MORNING = 3000

/**
 * 晚上祈祷列表
 */
const val LIST_TYPE_NIGHT = 4000

/**
 * 古兰经音频管理器
 */
object QuranAudioManager {

    /**
     * 当前挑战的currentChallengeQuranAudioBean
     */
    var currentChallengeQuranAudioBean = QuranAudioBean()

    /**
     * 古兰经音频列表
     */
    val quranList = mutableListOf<QuranAudioBean>()

    /**
     * 早上祈祷音频列表
     */
    val morningList = mutableListOf<QuranAudioBean>()

    /**
     * 晚上祈祷音频列表
     */
    val nightList = mutableListOf<QuranAudioBean>()

    /**
     * 收藏列表
     */
    val favoriteList = mutableListOf<QuranAudioBean>()

    /**
     * 收藏列表名称
     */
    val favoriteNameList =
        MusicSpUtils.getInstance(MusicConstant.SP_NAME).getString(SP_KEY_FAVORITE_MUSIC, "")
            .split(",").toMutableList()

    suspend fun buildMusicList() {
        withContext(Dispatchers.IO) {
            val musicBeanList = buildSourceList()
            //古兰经
            val quran = musicBeanList.filter {
                it.title.toIntOrNull() != null
            }.sortedBy {
                it.title.toString()
            }

            //早晨  名称固定不变 直接对比
            val morning = musicBeanList.filter {
                it.title == MORNING_QURAN_FILE_NAME
            }

            //晚上  名称固定不变 直接对比
            val night = musicBeanList.filter {
                it.title == NIGHT_QURAN_FILE_NAME
            }

            //收藏
            val favorite = favoriteNameList.filter { !TextUtils.isEmpty(it) }.map {
                val index = it.toInt() - 1
                quran[index]
            }
            quranList.clear()
            morningList.clear()
            nightList.clear()
            favoriteList.clear()

            quranList.addAll(quran)
            morningList.addAll(morning)
            nightList.addAll(night)
            favoriteList.addAll(favorite)
            Logger.e("quranList=${quranList}")
            Logger.e("morningList=${morningList}")
            Logger.e("nightList=${nightList}")
        }
    }

    suspend fun buildChallengeQuranAudioBean(quranIndex: Int) {
        withContext(Dispatchers.IO) {
            val challengeAudioBean = buildChallengeSource(quranIndex)
            withContext(Dispatchers.Main) {
                if (challengeAudioBean != null) {
                    currentChallengeQuranAudioBean = challengeAudioBean
                }
            }
        }
    }

    /**
     * 根据sdcard 音频目录中的音频文件生成原始数据集合
     */
    private fun buildSourceList(): MutableList<QuranAudioBean> {
        val source = mutableListOf<QuranAudioBean>()
        val quranAudiosFromDb = AppDatabase.get().quranAudioDao().queryAllQuranAudio()
        if (quranAudiosFromDb != null && quranAudiosFromDb.isNotEmpty()) {
            quranAudiosFromDb.forEach {
                Logger.e(it.toString())
                source.add(QuranAudioBean().apply {
                    id= it.id
                    nameEN = it.nameEN
                    nameAR = it.nameAR
                    title = it.title
                    artist = it.artist
                    album = it.album
                    albumId = it.albumId
                    coverPath = it.coverPath
                    duration = it.duration
                    path = it.path
                    fileName = it.fileName
                    fileSize = it.fileSize
                })
            }
        } else {
            val movies = File(Environment.getRootDirectory(), QURAN_DIR_NAME)
            Logger.e("path=${movies.absolutePath}")
            val files = movies.listFiles()?.filter { it.isFile && it.name.endsWith(".mp3") }
            if (files != null) {
                if (files.isNotEmpty()) {
                    files.forEach {
                        val retriever = MediaMetadataRetriever()
                        val filePath = it.absolutePath
                        retriever.setDataSource(filePath)

                        val durations =
                            retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)

                        source.add(QuranAudioBean().apply {
                            path = filePath
                            album =
                                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)
                            artist =
                                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
                                    ?: ""
                            title =
                                (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
                                    ?: it.name).replace(".mp3", "")

                            val index = title.toIntOrNull()
                            if (index != null) {
                                nameAR = quranInfoList[index - 1].nameAR
                                nameEN = quranInfoList[index - 1].nameEN
                            }
                            duration = durations!!.toLong()
                        })
                        source.forEach { audio ->
                            audio.id = audio.hashCode().toString()
                        }
                    }
                }

                val tempSource = mutableListOf<QuranAudio>()
                source.forEach {

                    tempSource.add(QuranAudio().apply {
                        id= it.id
                        nameEN = it.nameEN
                        nameAR = it.nameAR
                        title = it.title
                        artist = it.artist
                        album = it.album
                        albumId = it.albumId
                        coverPath = it.coverPath
                        duration = it.duration
                        path = it.path
                        fileName = it.fileName
                        fileSize = it.fileSize
                    })
                }
                AppDatabase.get().quranAudioDao().addBatchQuranAudio(tempSource)
            }
        }
        return source
    }


    /**
     * 根据sdcard 音频目录中的音频文件生成挑战数据集合
     */
    private fun buildChallengeSource(index: Int): QuranAudioBean? {
        val movies = File(Environment.getRootDirectory(), QURAN_DIR_NAME)
        val files = movies.listFiles()?.filter { it.isFile && it.name.endsWith(".mp3") }
        if (files != null) {
            if (files.isNotEmpty()) {
                files.forEach {
                    val retriever = MediaMetadataRetriever()
                    val filePath = it.absolutePath
                    retriever.setDataSource(filePath)

                    val fileTitle =
                        (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
                            ?: it.name).replace(".mp3", "")
                    val titleInt = fileTitle.toIntOrNull()
                    if (titleInt == index + 1) {
                        val durations =
                            retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)

                        return QuranAudioBean().apply {
                            path = filePath
                            album =
                                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)
                            artist =
                                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
                                    ?: ""
                            title =
                                (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
                                    ?: it.name).replace(".mp3", "")

                            val index = title.toIntOrNull()
                            if (index != null) {
                                nameAR = quranInfoList[index - 1].nameAR
                                nameEN = quranInfoList[index - 1].nameEN
                            }
                            duration = durations!!.toLong()
                            id = it.hashCode().toString()
                        }
                    }
                }
            }
        }
        return null
    }

    fun setFavorite(movieBean: QuranAudioBean): Boolean {
        val result = if (favoriteNameList.contains(movieBean.title)) {
            favoriteNameList.remove(movieBean.title)
            favoriteList.remove(movieBean)
            false
        } else {
            favoriteNameList.add(movieBean.title)
            favoriteList.add(movieBean)
            true
        }

        MusicSpUtils.getInstance(MusicConstant.SP_NAME)
            .put(SP_KEY_FAVORITE_MUSIC, favoriteNameList.joinToString(","))
        return result
    }


}

/**
 * 古兰经音频文件列表
 */
private val quranInfoList: List<QuranFileInfo>
    get() = listOf(
        QuranFileInfo(1, "Al-Fatihah", "الفاتحة", "001"),
        QuranFileInfo(2, "Al-Baqarah", "البقرة", "002"),
        QuranFileInfo(3, "Ali 'Imran", "آل عمران", "003"),
        QuranFileInfo(4, "An-Nisa", "النساء", "004"),
        QuranFileInfo(5, "Al-Ma'idah", "المائدة", "005"),
        QuranFileInfo(6, "Al-An'am", "الأنعام", "006"),
        QuranFileInfo(7, "Al-A'raf", "الأعراف", "007"),
        QuranFileInfo(8, "Al-Anfal", "الأنفال", "008"),
        QuranFileInfo(9, "At-Tawbah", "التوبة", "009"),
        QuranFileInfo(10, "Yunus", "يونس", "010"),
        QuranFileInfo(11, "Hud", "هود", "011"),
        QuranFileInfo(12, "Yusuf", "يوسف", "012"),
        QuranFileInfo(13, "Ar-Ra'd", "الرعد", "013"),
        QuranFileInfo(14, "Ibrahim", "ابراهيم", "014"),
        QuranFileInfo(15, "Al-Hijr", "الحجر", "015"),
        QuranFileInfo(16, "An-Nahl", "النحل", "016"),
        QuranFileInfo(17, "Al-Isra", "الإسراء", "017"),
        QuranFileInfo(18, "Al-Kahf", "الكهف", "018"),
        QuranFileInfo(19, "Maryam", "مريم", "019"),
        QuranFileInfo(20, "Taha", "طه", "020"),
        QuranFileInfo(21, "Al-Anbya", "الأنبياء", "021"),
        QuranFileInfo(22, "Al-Haj", "الحج", "022"),
        QuranFileInfo(23, "Al-Mu'minun", "المؤمنون", "023"),
        QuranFileInfo(24, "An-Nur", "النور", "024"),
        QuranFileInfo(25, "Al-Furqan", "الفرقان", "025"),
        QuranFileInfo(26, "Ash-Shu'ara", "الشعراء", "026"),
        QuranFileInfo(27, "An-Naml", "النمل", "027"),
        QuranFileInfo(28, "Al-Qasas", "القصص", "028"),
        QuranFileInfo(29, "Al-'Ankabut", "العنكبوت", "029"),
        QuranFileInfo(30, "Ar-Rum", "الروم", "030"),
        QuranFileInfo(31, "Luqman", "لقمان", "031"),
        QuranFileInfo(32, "As-Sajdah", "السجدة", "032"),
        QuranFileInfo(33, "Al-Ahzab", "الأحزاب", "033"),
        QuranFileInfo(34, "Saba", "سبأ", "034"),
        QuranFileInfo(35, "Fatir", "فاطر", "035"),
        QuranFileInfo(36, "Ya-Sin", "يس", "036"),
        QuranFileInfo(37, "As-Saffat", "الصافات", "037"),
        QuranFileInfo(38, "Sad", "ص", "038"),
        QuranFileInfo(39, "Az-Zumar", "الزمر", "039"),
        QuranFileInfo(40, "Ghafir", "غافر", "040"),
        QuranFileInfo(41, "Fussilat", "فصلت", "041"),
        QuranFileInfo(42, "Ash-Shuraa", "الشورى", "042"),
        QuranFileInfo(43, "Az-Zukhruf", "الزخرف", "043"),
        QuranFileInfo(44, "Ad-Dukhan", "الدخان", "044"),
        QuranFileInfo(45, "Al-Jathiyah", "الجاثية", "045"),
        QuranFileInfo(46, "Al-Ahqaf", "الأحقاف", "046"),
        QuranFileInfo(47, "Muhammad", "محمد", "047"),
        QuranFileInfo(48, "Al-Fath", "الفتح", "048"),
        QuranFileInfo(49, "Al-Hujurat", "الحجرات", "049"),
        QuranFileInfo(50, "Qaf", "سورة ق", "050"),
        QuranFileInfo(51, "Adh-Dhariyat", "الذاريات", "051"),
        QuranFileInfo(52, "At-Tur", "الطور", "052"),
        QuranFileInfo(53, "An-Najm", "النجم", "053"),
        QuranFileInfo(54, "Al-Qamar", "القمر", "054"),
        QuranFileInfo(55, "Ar-Rahman", "الرحمن", "055"),
        QuranFileInfo(56, "Al-Waqi'ah", "الواقعة", "056"),
        QuranFileInfo(57, "Al-Hadid", "الحديد", "057"),
        QuranFileInfo(58, "Al-Mujadila", "المجادلة", "058"),
        QuranFileInfo(59, "Al-Hashr", "الحشر", "059"),
        QuranFileInfo(60, "Al-Mumtahanah", "الممتحنة", "060"),
        QuranFileInfo(61, "As-Saf", "الصف", "061"),
        QuranFileInfo(62, "Al-Jumu'ah", "الجمعة", "062"),
        QuranFileInfo(63, "Al-Munafiqun", "المنافقون", "063"),
        QuranFileInfo(64, "At-Taghabun", "التغابن", "064"),
        QuranFileInfo(65, "At-Talaq", "الطلاق", "065"),
        QuranFileInfo(66, "At-Tahrim", "التحريم", "066"),
        QuranFileInfo(67, "Al-Mulk", "الملك", "067"),
        QuranFileInfo(68, "Al-Qalam", "القلم", "068"),
        QuranFileInfo(69, "Al-Haqqah", "الحاقة", "069"),
        QuranFileInfo(70, "Al-Ma'arij", "المعارج", "070"),
        QuranFileInfo(71, "Nuh", "نوح", "071"),
        QuranFileInfo(72, "Al-Jinn", "الجن", "072"),
        QuranFileInfo(73, "Al-Muzzammil", "المزمل", "073"),
        QuranFileInfo(74, "Al-Muddaththir", "المدثر", "074"),
        QuranFileInfo(75, "Al-Qiyamah", "القيامة", "075"),
        QuranFileInfo(76, "Al-Insan", "الإنسان", "076"),
        QuranFileInfo(77, "Al-Mursalat", "المرسلات", "077"),
        QuranFileInfo(78, "An-Naba", "النبأ", "078"),
        QuranFileInfo(79, "An-Nazi'at", "النازعات", "079"),
        QuranFileInfo(80, "Abasa", "عبس", "080"),
        QuranFileInfo(81, "At-Takwir", "التكوير", "081"),
        QuranFileInfo(82, "Al-Infitar", "الإنفطار", "082"),
        QuranFileInfo(83, "Al-Mutaffifin", "المطففين", "083"),
        QuranFileInfo(84, "Al-Inshiqaq", "الانشقاق", "084"),
        QuranFileInfo(85, "Al-Buruj", "البروج", "085"),
        QuranFileInfo(86, "At-Tariq", "الطارق", "086"),
        QuranFileInfo(87, "Al-A'la", "الأعلى", "087"),
        QuranFileInfo(88, "Al-Ghashiyah", "الغاشية", "088"),
        QuranFileInfo(89, "Al-Fajr", "الفجر", "089"),
        QuranFileInfo(90, "Al-Balad", "البلد", "090"),
        QuranFileInfo(91, "Ash-Shams", "الشمس", "091"),
        QuranFileInfo(92, "Al-Layl", "الليل", "092"),
        QuranFileInfo(93, "Ad-Duhaa", "الضحى", "093"),
        QuranFileInfo(94, "Ash-Sharh", "الشرح", "094"),
        QuranFileInfo(95, "At-Tin", "التين", "095"),
        QuranFileInfo(96, "Al-'Alaq", "العلق", "096"),
        QuranFileInfo(97, "Al-Qadr", "القدر", "097"),
        QuranFileInfo(98, "Al-Bayyinah", "البينة", "098"),
        QuranFileInfo(99, "Az-Zalzalah", "الزلزلة", "099"),
        QuranFileInfo(100, "Al-'Adiyat", "العاديات", "100"),
        QuranFileInfo(101, "Al-Qari'ah", "القارعة", "101"),
        QuranFileInfo(102, "At-Takathur", "التكاثر", "102"),
        QuranFileInfo(103, "Al-'Asr", "العصر", "103"),
        QuranFileInfo(104, "Al-Humazah", "الهمزة", "104"),
        QuranFileInfo(105, "Al-Fil", "الفيل", "105"),
        QuranFileInfo(106, "Quraysh", "قريش", "106"),
        QuranFileInfo(107, "Al-Ma'un", "الماعون", "107"),
        QuranFileInfo(108, "Al-Kawthar", "الكوثر", "108"),
        QuranFileInfo(109, "Al-Kafirun", "الكافرون", "109"),
        QuranFileInfo(110, "An-Nasr", "النصر", "110"),
        QuranFileInfo(111, "Al-Masad", "المسد", "111"),
        QuranFileInfo(112, "Al-Ikhlas", "الإخلاص", "112"),
        QuranFileInfo(113, "Al-Falaq", "الفلق", "113"),
        QuranFileInfo(114, "An-Nas", "الناس", "114"),
    )